package com.my.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.my.entity.*;
import com.my.service.*;
import com.my.util.Rest;
import com.my.util.ScheduleUtil;
import org.quartz.SchedulerException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
public class TestPaperController {

    @Resource
    private TestPaperService service;

    @Resource
    private StudentService sService;

    @Resource
    private StudentTestPaperService stpService;

    @Resource
    private SchedulerValueService svService;

    @Resource
    private TokenService tService;

    @Resource
    private QuestionService qService;

    @Resource
    private ScheduleUtil scheduleUtil;

    @PostMapping("paper/get")
    public Rest get(@RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "10") int pageSize, @RequestBody TestPaper paper) {
        return Rest.ok().setData("page", service.getPage(new Page<>(pageNo, pageSize), paper));
    }

    @PostMapping("papers")
    public Rest add(@RequestBody TestPaper paper) {
        if(service.save(paper)) {
            return Rest.ok("添加成功！");
        }
        return Rest.err("发生错误！");
    }

    @PutMapping("papers")
    public Rest edit(@RequestBody TestPaper paper) {
        if(service.updateById(paper)) {
            return Rest.ok("修改成功！");
        }
        return Rest.err("修改失败！");
    }

    @DeleteMapping("papers")
    public Rest del(Long id) {
        if(service.removeById(id)) {
            return Rest.ok("删除成功！");
        }
        return Rest.err("删除失败！");
    }

    @Transactional(rollbackFor = Exception.class)
    @GetMapping("paper/release")
    public Rest release(Long id) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, SchedulerException, IllegalAccessException {
        TestPaper paper = service.getById(id);
        if(paper.getStartTime().getTime() < System.currentTimeMillis()) {
            return Rest.err("考试开始时间必须大于当前时间！");
        }
        if(service.updateById(new TestPaper().setId(id).setStatus(2))) {
            String uuid = StrUtil.uuid();
            SchedulerValue schedulerValue = new SchedulerValue().setStartTime(DateUtil.offsetMinute(paper.getStartTime(), paper.getDuration())).setClassName("com.my.job.TestPaperJob").setJobName("Job" + id).setMethodName("execution").setOnce(true).setTriggerName("TestPaper" + id).setTriggerGroupName("TestPaperGroup" + id).setUuid(uuid);
            schedulerValue.setRemark(new JSONObject().putOnce("id", id).putOpt("uuid", uuid).putOpt("schedulerValue", schedulerValue).toString());
            svService.save(schedulerValue);
            scheduleUtil.addJob(schedulerValue);
            scheduleUtil.startJobAll();
            return Rest.ok("发布成功！");
        }
        return Rest.err("发布失败！");
    }

    @GetMapping("paper/{id}")
    public Rest getById(@PathVariable("id") Long id) {
        return Rest.ok().setData("question", service.getById(id));
    }

    @PostMapping("submitTestPaper")
    public Rest submitTestPaper(@RequestHeader("authentication-token") String to, Long id, @RequestBody JSONArray array) {
        Token token = tService.getById(to);
        TestPaper paper = service.getById(id);
        Map<Long, String> map = qService.list(new QueryWrapper<Question>().eq("subject_id", paper.getSubjectId())).stream().collect(Collectors.toMap(Question::getId, Question::getCorrect));
        double count = 0, correct = 0, score = 0;
        for (JSONObject o : array.jsonIter()) {
            ++count;
            if(o.getStr("label").equals(map.get(o.getLong("id")))) {
                ++correct;
            }
        }
        if(count != 0) {
            score = correct / count * 100;
        }
        if(stpService.save(new StudentTestPaper().setStudentId(token.getUserId()).setTestPaperId(id).setScore((int)score))) {
            return Rest.ok("提交成功！");
        }else {
            return Rest.ok("发生错误!");
        }
    }

    @GetMapping("getTestPaperByStudentId")
    public Rest getTestPaperByStudentId(@RequestHeader("authentication-token") String to, @RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "10") int pageSize) {
        return Rest.ok().setData("page", service.getTestPaperByStudentId(new Page<>(pageNo, pageSize), tService.getById(to).getUserId()));
    }

}
